home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / endo / plot.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  10KB  |  252 lines

  1. /*************************************************************************
  2.  *                                                                       *
  3.  *  Copyright (c) 1992, 1993 Ronald Joe Record                           *
  4.  *                                                                       *
  5.  *  All rights reserved. No part of this program or publication may be   *
  6.  *  reproduced, transmitted, transcribed, stored in a retrieval system,  *
  7.  *  or translated into any language or computer language, in any form or *
  8.  *  by any means, electronic, mechanical, magnetic, optical, chemical,   *
  9.  *  biological, or otherwise, without the prior written permission of:   *
  10.  *                                                                       *
  11.  *      Ronald Joe Record (408) 458-3718                                 *
  12.  *      212 Owen St., Santa Cruz, California 95062 USA                   *
  13.  *                                                                       *
  14.  *************************************************************************/
  15.  
  16. /***************************************************************************
  17.  *                                                                         *
  18.  *     Copyright (c) 1989                  Hiram Clawson                   *
  19.  *                                                                         *
  20.  *  All rights reserved. No part of this program or publication may be     *
  21.  *  reproduced, transmitted, transcribed, stored in a retrieval system,    *
  22.  *  or translated into any language or computer language, in any form or   *
  23.  *  by any means, electronic, mechanical, magnetic, optical, chemical,     *
  24.  *  biological, or otherwise, without the prior written permission of:     *
  25.  *                                                                         *
  26.  *          Hiram Clawson            (408) 429-5647                        *
  27.  *          P. O. Box 3178, Santa Cruz, California 95063-3178 USA          *
  28.  *                                                                         *
  29.  ***************************************************************************/
  30. /***************************************************************************
  31.  *    plot.c: Plot a 3D point through a window in 3D space that            *
  32.  *        is the computer display screen.                                  *
  33.  *                                                                         *
  34.  *        Written by Hiram Clawson.                                        *
  35.  *        Ported to X11 by Ronald Joe Record.                              *
  36.  ***************************************************************************/
  37.  
  38. #include "globals.h"
  39.  
  40. int plot( _3D_point, _2D_point )    /* returns TRUE when on screen */
  41. triple _3D_point;
  42. xy_t *_2D_point;
  43. {
  44. /*
  45.  *    Given a point in 3D space: _3D_point.x, _3D_point.y, _3D_point.z
  46.  *        and a screen center of (screen_center.x, screen_center.y)
  47.  *        (upper left is 0,0), lower right is (screen_max.x,screen_max.y)
  48.  *        (lower left is 0,0), upper right is (screen_max.x,screen_max.y)
  49.  *
  50.  *    return plot point _2D_point->x, _2D_point->y as seen through a window
  51.  *        from the viewpoint (view_point.x, view_point.y, view_point.z)
  52.  *
  53.  *    The window is an arbitary plane in x,y,z space defined by four points:
  54.  *        window center            (window_center.x, .y, .z)
  55.  *        top middle of window    (window_top.x, .y, .z)
  56.  *        right middle            (window_right.x, .y, .z)
  57.  *        upper right window corner(window_upper_right.x, .y, .z)
  58.  *
  59.  *    The viewpoint is on a perpendicular (to the window plane) line through
  60.  *        the center to the window.
  61.  *
  62.  *    There are some global constants floating around that were set up by
  63.  *    view_point_constants concerning the window.  When the window
  64.  *    is moved they are recomputed by view_point_constants.
  65.  *    They are vectors associated with the window points and the length
  66.  *    of those vectors.
  67.  *
  68.  *        vector v_center_top, length_center_top
  69.  *        vector v_center_right length_center_right
  70.  *        vector v_view_center length_view_center
  71.  */
  72.  
  73. /*    local variables */
  74.  
  75.     triple v_view_point;/* from view point to 3D point in question */
  76.     double length_view_point;    /* length of vector v_view_point */
  77.     triple window;    /* intersection point of window plane and */
  78.                 /* the vector v_view_point */
  79.     double cosine_theta;    /* computed cosine of angle theta */
  80.     xy_t screen;        /* computed screen x and y points */
  81.     double cosine_alpha;    /* between v_center_right and v_center_window */
  82.     double sine_alpha;    /* between v_center_right and v_center_window */
  83.     double cosine_beta;    /* between v_center_top and v_center_windos */
  84.     double dtemp;            /* for temporary double */
  85.     triple lambda_view_point;    /* from view point to 3D point */
  86.     triple v_view_window;    /* from view point to window intersect*/
  87.     double length_view_window;        /* length from view to window */
  88.     triple v_center_window;    /* from center to window intersection */
  89.     double length_center_window_squared;
  90.     double length_center_window;    /* length from center to intersection */
  91.     
  92. /*    code starts here    **********************************************/
  93.  
  94. /*    assume point is not in view */
  95.  
  96.     _2D_point->x    = 0;
  97.     _2D_point->y    = 0;
  98.  
  99. /* compute vector  v_view_point: view point to 3D point in question */
  100.  
  101.     VECTORIZE( v_view_point, view_point, _3D_point );
  102.  
  103. /*
  104.  * length of vector v_view_point (check point in question is not EXACTLY
  105.  *    at the same place as the view point otherwise sqrt will give error)
  106.  */
  107.  
  108.     if ( POINTS_NOT_EQUAL( view_point, _3D_point ) )
  109.     {
  110.         length_view_point = VECTOR_LENGTH( v_view_point );
  111.     }
  112.     else
  113.     {
  114.         return( FALSE );
  115.     }
  116.  
  117. /*
  118.  *  if length is not more than that from view point to window, ignore
  119.  *    the point, and exit here because point is not in view
  120.  */
  121.  
  122.     if( length_view_point <= length_view_center )
  123.     {
  124.         return( FALSE );
  125.     }
  126.  
  127. /*
  128.  *  compute angle between vector v_view_center and v_view_point
  129.  *        for angles -90 to +90 cosine_theta is between 0 and 1
  130.  *        for angles greater than 90 degrees, cosine_theta is negative
  131.  */
  132.  
  133.     if ( (cosine_theta = (    DOT_PRODUCT( v_view_center, v_view_point ) )/
  134.                 (length_view_point * length_view_center) )
  135.             <= cosine_half_field_of_view )
  136.     {
  137.         /* cosine_theta is less than half of the field
  138.         of view, which means the point is not visible on the screen */
  139.         return(FALSE);
  140.     }
  141.  
  142. /*
  143.  * Point is on the screen, plot it.
  144.  *
  145.  * compute length along vector v_view_point to its intersection with the
  146.  *    plane of the window
  147.  */
  148.  
  149.     length_view_window = length_view_center / cosine_theta;
  150.  
  151. /* unit vector on vector v_view_point is */
  152.  
  153.     UNIT_VECTOR( lambda_view_point, v_view_point, length_view_point );
  154.  
  155. /* vector view point to the window along the vector v_view_point is */
  156.  
  157.     VECTOR_X_SCALAR( v_view_window, lambda_view_point, length_view_window );
  158.  
  159. /* window point is view point plus vector v_view_window */
  160.  
  161.     POINT_PLUS_VECTOR( window, view_point, v_view_window );
  162.  
  163. /* now to find which quadrant on the screen this point is at */
  164.  
  165. /* vector from center of window to the window point is */
  166.  
  167.     VECTORIZE( v_center_window, window_center, window );
  168.  
  169. /* length squared of v_center_window */
  170.  
  171.     length_center_window_squared =    (v_center_window.x * v_center_window.x)+
  172.                     (v_center_window.y * v_center_window.y)+
  173.                     (v_center_window.z * v_center_window.z);
  174.  
  175. /*    compute angle between vectors v_center_window and v_center_right */
  176.  
  177.     if( length_center_window_squared > 0.0 )
  178.     {
  179.         length_center_window = sqrt( length_center_window_squared );
  180.         cosine_alpha=((DOT_PRODUCT(v_center_window, v_center_right ) ) /
  181.                 (length_center_right * length_center_window) );
  182.         cosine_beta=((DOT_PRODUCT( v_center_window, v_center_top ) ) /
  183.                 (length_center_top * length_center_window) );
  184.     }
  185.     else    /* we have a point directly at screen center */
  186.     {
  187.         _2D_point->x    = screen_center.x;
  188.         _2D_point->y    = screen_center.y;
  189.         return( TRUE );
  190.     }
  191.  
  192. /*
  193.  * the two angles alpha and beta are computed to help find the quadrant.
  194.  *    for quadrant x > 0, y > 0    cos_alpha > 0 and cos_beta > 0
  195.  *    for quadrant x < 0, y > 0    cos_alpha < 0 and cos_beta > 0
  196.  *    for quadrant x < 0, y < 0    cos_alpha < 0 and cos_beta < 0
  197.  *    for quadrant x > 0, y < 0    cos_alpha > 0 and cos_beta < 0
  198.  *
  199.  *    now have an angle and a length on the screen, plot the point
  200.  *    get the sine from the cosine. ( sin*sin + cos*cos ) = 1
  201.  *    sin = sqrt( 1 - (cos*cos) )
  202.  */
  203.  
  204.     if ( (dtemp=(cosine_alpha * cosine_alpha)) >= 1.0 )
  205.         sine_alpha = 0.0;    /* overflow protection */
  206.     else /* sometimes cos*cos is slightly over 1.0 by round off error */
  207.         sine_alpha = sqrt( 1.0 - dtemp );
  208.  
  209.     if ( cosine_beta < 0.0 )    /* quadrant is where y < 0 */
  210.         sine_alpha = - sine_alpha;
  211.  
  212. /*
  213.  *    Here as calculated,
  214.  *    screen.x and .y are the x and y components of the vector v_center_window
  215.  *        in the screen pixel units based on a coordinate system that is
  216.  *        a normal x positive to right, y positive up.
  217.  */
  218.     screen.x = length_center_window * cosine_alpha / _3D_units_per_ypixel;
  219.     screen.y = length_center_window * sine_alpha / _3D_units_per_ypixel;
  220.  
  221. /*
  222.  *    convert to coordinate system of the video screen where y is positive
  223.  *        down.
  224.  *    (needed when coord system is (0,0) upper left, (maxx, maxy) lower right)
  225.  *    (NOTE: commented out for CGI)
  226.     screen.x = (screen.x * aspect_ratio) + screen_center.x;
  227.     screen.y = screen_center.y - screen.y;
  228.  * 
  229.  *    In the case of (0,0) lower left and (maxx, maxy) upper right, just
  230.  *    adjust for aspect ratio. (This is CGI.)
  231.  */
  232.     screen.x = screen.x + screen_center.x;
  233.     screen.y = screen_center.y + screen.y;
  234.  
  235. /* final limit checks, just in case. */
  236.  
  237.     if (    (screen.x < 0) || (screen.x > screen_max.x) ||
  238.         (screen.y < 0) || (screen.y > screen_max.y) )
  239.     {
  240.         return(FALSE);    /* something went wrong */
  241.     }
  242.     else
  243.     {
  244.         _2D_point->x = screen.x;
  245.         _2D_point->y = screen.y;
  246.         return( TRUE );    /* plot is OK */
  247.     }
  248.  
  249.     return( FALSE );    /* should NEVER get to here */
  250.  
  251. }    /* end of plot */
  252.